﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;
using CommunityToolkit.Mvvm.Collections;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Win32;
using Protocal.App.Common;
using 多协议通信平台.Common;
using 多协议通信平台.Entity;
using 多协议通信平台.Models;
using 多协议通信平台.ViewModels.Component;

namespace 多协议通信平台.ViewModels
{
    public partial class MainViewModel : ObservableObject,IDisposable
    {
        private System.Timers.Timer _timer;

        [ObservableProperty]
        private DateTime currentTime = DateTime.Now;

        [ObservableProperty]
        private int selectedTabIdx;

        [ObservableProperty]
        private double treeViewItemWidth = 230;

        [ObservableProperty]
        private UserModel userModel;

        private bool collapsed = false;

        private FrameworkElement currentElem;

        public static ObservableCollection<FrameworkElement> TabList { get; set; } = new ObservableCollection<FrameworkElement>();

        public ObservableCollection<string> DefaultAvatars { get; set; } = new ObservableCollection<string>();

        public ObservableCollection<MenuItemViewModel> Menus { get; set; } = new ObservableCollection<MenuItemViewModel>();

        public MainViewModel()
        {
            _timer = new System.Timers.Timer();
            _timer.AutoReset = true;
            _timer.Elapsed += _timer_Elapsed;
            _timer.Interval = 1000;
            _timer.Start();

            userModel = ContextHelper.Get<UserModel>("user");
            InitMenus();
            InitAvatars();
            TabList.CollectionChanged += TabList_CollectionChanged;
        }

        private void TabList_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if (TabList.Count == 0)
                SelectedTabIdx = -1;
        }

        private void InitMenus()
        {
            string nsp_prefix = "多协议通信平台";
            // &#xe70c; => \ue70c
            MenuItemViewModel item1 = new MenuItemViewModel() { Id = 1, ParentId = 0, MenuName = "Modbus通信", UrlName = $"{nsp_prefix}.Views.Protocal.ModbusView", MenuIcon = "\ue645", OpenViewCommand = new CommunityToolkit.Mvvm.Input.RelayCommand<MenuItemViewModel>(OpenView) };
            item1.Children = new ObservableCollection<MenuItemViewModel>();
            //item1.Children.Add(new MenuItemViewModel() { Id = 101, ParentId = 1, MenuName = "ModbusASCII通信", UrlName = $"{nsp_prefix}.Views.Protocal.ModbusAsciiView",MenuIcon = "\ue750", OpenViewCommand = new CommunityToolkit.Mvvm.Input.RelayCommand<MenuItemViewModel>(OpenView) });
            //item1.Children.Add(new MenuItemViewModel() { Id = 102, ParentId = 1, MenuName = "ModbusRTU通信", UrlName = $"{nsp_prefix}.Views.Protocal.ModbusRtuView",MenuIcon = "\ue647",OpenViewCommand = new CommunityToolkit.Mvvm.Input.RelayCommand<MenuItemViewModel>(OpenView) });
            //item1.Children.Add(new MenuItemViewModel() { Id = 103, ParentId = 1, MenuName = "ModbusTCP通信", UrlName = $"{nsp_prefix}.Views.Protocal.ModbusTcpView",MenuIcon = "\ue646",OpenViewCommand = new CommunityToolkit.Mvvm.Input.RelayCommand<MenuItemViewModel>(OpenView) });

            MenuItemViewModel item2 = new MenuItemViewModel() { Id = 2, ParentId = 0, MenuName = "欧姆龙通信", UrlName = "", MenuIcon = "\ue70c", OpenViewCommand = new CommunityToolkit.Mvvm.Input.RelayCommand<MenuItemViewModel>(OpenView) };
            item2.Children = new ObservableCollection<MenuItemViewModel>();
            item2.Children.Add(new MenuItemViewModel() { Id = 201, ParentId = 2, MenuName = "FINS通信", UrlName = $"{nsp_prefix}.Views.Protocal.FinsView",MenuIcon = "\ue6fb",OpenViewCommand = new CommunityToolkit.Mvvm.Input.RelayCommand<MenuItemViewModel>(OpenView) });
            item2.Children.Add(new MenuItemViewModel() { Id = 202, ParentId = 2, MenuName = "FINSTCP通信", UrlName = $"{nsp_prefix}.Views.Protocal.FinsTcpView",MenuIcon = "\ue6fb",OpenViewCommand = new CommunityToolkit.Mvvm.Input.RelayCommand<MenuItemViewModel>(OpenView) });
            item2.Children.Add(new MenuItemViewModel() { Id = 203, ParentId = 2, MenuName = "CIP通信", UrlName = $"{nsp_prefix}.Views.Protocal.CipView",MenuIcon = "\ue6fb",OpenViewCommand = new CommunityToolkit.Mvvm.Input.RelayCommand<MenuItemViewModel>(OpenView) });

            MenuItemViewModel item3 = new MenuItemViewModel() { Id = 3, ParentId = 0, MenuName = "S7通信", UrlName = $"{nsp_prefix}.Views.Protocal.S7View", MenuIcon = "\ue6c1", OpenViewCommand = new CommunityToolkit.Mvvm.Input.RelayCommand<MenuItemViewModel>(OpenView) };
            MenuItemViewModel item4 = new MenuItemViewModel() { Id = 4, ParentId = 0, MenuName = "MC3E通信", UrlName = $"{nsp_prefix}.Views.Protocal.Mc3eView",MenuIcon = "\ue742",OpenViewCommand = new CommunityToolkit.Mvvm.Input.RelayCommand<MenuItemViewModel>(OpenView) };
            MenuItemViewModel item5 = new MenuItemViewModel() { Id = 5, ParentId = 0, MenuName = "SECSGEM通信", UrlName = $"{nsp_prefix}.Views.Protocal.SecsGemView",MenuIcon = "\ue81f",OpenViewCommand = new CommunityToolkit.Mvvm.Input.RelayCommand<MenuItemViewModel>(OpenView) };

            Menus.Add(item1);
            Menus.Add(item2);
            Menus.Add(item3);
            Menus.Add(item4);
            Menus.Add(item5);
        }

        private void InitAvatars()
        {
            for (int i = 1; i < 18; i++)
            {
                DefaultAvatars.Add($"pack://siteofOrigin:,,,/Assets/Avatars/a{i:d2}.jpg");
            }
            DefaultAvatars.Add("pack://siteofOrigin:,,,/Assets/Avatars/choose.png");
        }

        private void OpenView(MenuItemViewModel? model)
        {
            if (model == null) return;
            model.IsExpand = !model.IsExpand;

            string urlName = model.UrlName;
            if (string.IsNullOrEmpty(urlName)) return;
            FrameworkElement element = IocHelper.GetInstance(urlName);
            currentElem = element;
            if (!TabList.Contains(element))
                TabList.Add(element);
            SelectedTabIdx = TabList.IndexOf(element);
        }


        private void _timer_Elapsed(object? sender, ElapsedEventArgs e)
        {
            CurrentTime = CurrentTime.AddSeconds(1);
        }

        [RelayCommand]
        private void MenuCollpase(object obj)
        {
            var column = obj as ColumnDefinition;
            collapsed = column.Width.Value == 240;
            GridLength targetWidth = collapsed ? new GridLength(68) : new GridLength(240);

            GridLengthAnimation animation = new GridLengthAnimation
            {
                From = column.Width,
                To = targetWidth,
                Duration = TimeSpan.FromSeconds(0.3),
                EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut }
            };

            column.BeginAnimation(ColumnDefinition.WidthProperty, animation);
            TreeViewItemWidth = collapsed ? 60 : 230;
            if (collapsed)
            {
                foreach (var menu in Menus)
                {
                    menu.IsExpand = false;
                }
            }
        }

        string initDir = "";
        [RelayCommand]
        private void ChangeAvatar(object obj)
        {
            string path = obj.ToString();
            if (path.Substring(path.LastIndexOf("/")).Contains("choose"))
            {
                OpenFileDialog dialog = new OpenFileDialog();
                dialog.Filter = "图片文件 | *.jpg;*.png;*.jpeg;*.bmp";
                dialog.Multiselect = false;
                if(!string.IsNullOrEmpty(initDir)) 
                    dialog.InitialDirectory = initDir;
                if (dialog.ShowDialog() == true)
                {
                    string file = dialog.FileName;
                    initDir = Path.GetDirectoryName(file);
                    userModel.Avatar = file;
                    // 同步sqlite数据库
                    Task.Run(() =>
                    {
                        IService.IBaseService service = IocHelper.GetService();
                        service.UpdateRange<Data_LocalRecord>(r => r.Id == userModel.Id, setter => setter.SetProperty(d=>d.Avatar,userModel.Avatar));
                    });
                    // TODO: 访问后端接口同步数据

                }
            }
            else
            {
                userModel.Avatar = path;
                // 同步sqlite数据库
                Task.Run(() =>
                {
                    IService.IBaseService service = IocHelper.GetService();
                    service.UpdateRange<Data_LocalRecord>(r => r.Id == userModel.Id, setter => setter.SetProperty(d => d.Avatar, userModel.Avatar));
                });
                // TODO: 访问后端接口同步数据
            }
        }

        public void Dispose()
        {
            _timer?.Stop();
            _timer?.Dispose();
        }
    }
}
